package ar.uba.fi.tecnicas.vista;

import java.awt.BorderLayout;
import java.awt.Point;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.Observable;
import java.util.Observer;

import javax.swing.JFrame;
import javax.swing.JOptionPane;

import ar.uba.fi.tecnicas.fabrica.Terreno;
import ar.uba.fi.tecnicas.fabrica.TipoMaquina;
import ar.uba.fi.tecnicas.fabrica.Terreno.ModoAdquisicion;
import ar.uba.fi.tecnicas.juego.Juego;
import ar.uba.fi.tecnicas.vista.PanelFabrica.IFabricaObserver;

public class FrameJuego extends JFrame implements Observer
{
	private static final long serialVersionUID = 0;
	
	private PanelFabrica panelFabrica;
	private PanelControles panelControles;
	private PanelInformacion panelInformacion;
	
	private Juego juego = Juego.instancia;
	
	public FrameJuego()
	{
		super("Simulador Fabrica");

		this.panelFabrica = new PanelFabrica();
		this.panelControles = new PanelControles(this);
		this.panelInformacion = new PanelInformacion();

		juego.getJugador().agregarVistaFabrica(panelFabrica);
		
		juego.addObserver(this);
		
		this.addWindowListener(new WindowAdapter() 
		{
			public void windowClosing(WindowEvent e) 
			{
				System.exit(0);
			}
		});
		
		this.setSize(700, 500);
		
		this.add(this.panelFabrica, BorderLayout.CENTER);
		this.add(this.panelControles, BorderLayout.EAST);
		this.add(this.panelInformacion, BorderLayout.SOUTH);
	}

	public void adquirirTerreno(Terreno terreno, ModoAdquisicion modo)
	{
		try
		{
			juego.getJugador().comprarTerreno(terreno, modo);
		}
		catch (Exception e) 
		{
			JOptionPane.showMessageDialog(this, e.getMessage());
		}
	}

	public void ubicarSalidaFabrica(Point posicion) 
	{	
		try
		{
			this.juego.getJugador().ubicarSalidaFabrica(posicion);
		}
		catch (Exception e) 
		{
			JOptionPane.showMessageDialog(this, e.getMessage());
		}		
	}

	public void crearNuevaLinea(String nombre) 
	{
		this.juego.getJugador().crearLineaProduccion(nombre);
	}

	public void comprarMaquina(TipoMaquina tipo, Point posicion, int indexLineaProduccion) 
	{
		try
		{
			this.juego.getJugador().comprarMaquina(tipo, posicion, indexLineaProduccion);
		}
		catch (Exception e) 
		{
			JOptionPane.showMessageDialog(this, e.getMessage());
		}
	}

	public void conectarMaquinas(Point posicionOrigen, Point posicionDestino) 
	{
		try
		{
			this.juego.getJugador().conectarMaquinas(posicionOrigen, posicionDestino);
		}
		catch (Exception e) 
		{
			JOptionPane.showMessageDialog(this, e.getMessage());
		}
	}
	
	public void seleccionarPrimeraMaquina(int indexLineaProduccion, Point posicion) 
	{
		try
		{
			this.juego.getJugador().seleccionarPrimeraMaquina(indexLineaProduccion, posicion);
		}
		catch (Exception e) 
		{
			JOptionPane.showMessageDialog(this, e.getMessage());
		}		
	}
	
	public void descongelarTiempo() 
	{
		this.juego.descongelarTiempo();
	}

	public void congelarTiempo() 
	{
		this.juego.congelarTiempo();
	}
	
	public Juego getJuego()
	{
		return Juego.instancia;
	}

	public void agregarListenerPanelFabrica(IFabricaObserver listener) 
	{
		this.panelFabrica.agregarListener(listener);		
	}
	
	public void quitarListenerPanelFabrica(IFabricaObserver listener) 
	{
		this.panelFabrica.quitarListener(listener);		
	}
	
	public void update(Observable observable, Object args)
	{
		if(args != null)
		{
			Exception ex = (Exception)args;
			String mensaje = ex.getMessage() != null ? ex.getMessage() : ex.getClass().toString(); 
			JOptionPane.showMessageDialog(this, mensaje);
			
			juego.congelarTiempo();
		}

		this.panelInformacion.refrescarInformacion();
		this.panelInformacion.repaint();
	}
	
	public static void main(String args[])
	{
		String nombre = JOptionPane.showInputDialog("Ingresar nombre jugador:");
		Juego.instancia.crearJugador(nombre);
		
		FrameJuego vistaJuego = new FrameJuego();
		vistaJuego.setVisible(true);
		
		setUpInicialParaPrueba(null);
	}
	
	/**
	 * Para probar el juego
	 */
	public static void setUpInicialParaPrueba(JFrame frame)
	{		
		
		try
		{
			/// Comprar terreno
			Juego.instancia.getJugador().comprarTerreno((Terreno)Juego.instancia.getTerrenos().toArray()[0], ModoAdquisicion.Compra);
			/// Crear Linea 1
			Juego.instancia.getJugador().crearLineaProduccion("Linea 1");
			Juego.instancia.getJugador().crearLineaProduccion("Linea 2");
			/// Comprar maquina 1
			Juego.instancia.getJugador().comprarMaquina(
				(TipoMaquina)Juego.instancia.getTiposMaquina().toArray()[1],
				new Point(10, 10),
				0
			);			
			/// Comprar maquina 2
			Juego.instancia.getJugador().comprarMaquina(
				(TipoMaquina)Juego.instancia.getTiposMaquina().toArray()[2],
				new Point(20, 10),
				0
			);
			
			/// Comprar maquina 2
			Juego.instancia.getJugador().comprarMaquina(
				(TipoMaquina)Juego.instancia.getTiposMaquina().toArray()[0],
				new Point(30, 10),
				0
			);
			
			Juego.instancia.getJugador().ubicarSalidaFabrica(new Point(40,10));
			
			Juego.instancia.getJugador().conectarMaquinas(new Point(10, 10), new Point(20, 10));
			Juego.instancia.getJugador().conectarMaquinas(new Point(20, 10), new Point(30, 10));
			Juego.instancia.getJugador().conectarMaquinas(new Point(30, 10), new Point(40, 10));
		}
		catch (Exception e) 
		{
			JOptionPane.showMessageDialog(frame, e.getMessage());
		}
	}
}
